/*-------------------------------------------------------------------------
***************** Modification History ***********************************
@doc
@module CPACbat.c - API functions for the ISO batch structure |
@end

$Log: /SoftPay/SPK2SIM/Source/CPACSrc/CPACbat.c $
**************************************************************************

   Copyright (C) 1999 by VeriFone, Inc.

   All rights reserved.  No part of this software may be reproduced,
   transmitted, transcribed, stored in a retrieval system, or translated
   into any language or computer language, in any form or by any means,
   electronic, mechanical, magnetic, optical, chemical, manual or otherwise,
   without the prior written permission of VeriFone, Inc.

---------------------------------------------------------------------------*/
#include <project.h>
#include <dbmgr.h>
#include <aclstr.h>
#include <iso8583.h>
#include <amexhost.h>

/** /#define DEBUG_VSIBATCH*/
#ifdef DEBUG_VSIBATCH
#define DEBUG_95
#endif

#ifdef AMEXPIP_DEFINED

#include <stdlib.h>
#include <define.h>
#include <transact.h>
#include <tran.h>
#include <gds.h>
#include <bdt.h>
#include <cdt.h>
#include <hdt.h>
#include <tct.h>
#include <mht.h>
#include <msg.h>
#include <trt.h>
#include <util.h>
#include <spdebug.h>
#include <ifldtbl.h>
#include <string.h>
#include <msgfuncs.h> /* CITI_PHIL */
#include <batmsg.h>  /* CITI_PHIL */
#include <fields.h>
#include "CPACids.h"
#include "CPACsize.h"
#include "CPACbat.h"

extern long lnGetSTAN(void);
extern int inGetBatchFieldData(BATCH_REC* psrBRec,unsigned int uiFieldID,unsigned char* pchData,unsigned short shMaxLength);
extern int inStoreBatchFieldData(BATCH_REC* psrBRec,unsigned int uiFieldID,unsigned char* pchData,unsigned short shDataLength);
extern int inGetOTInvBatchRec(TRANSACTION_OBJECT* pobTran,int inKey,long lnDBWhat);//1.4
//CPAC_LINT_ADDED
extern VS_BOOL fGetDemoMode(void);


/*********************************************************************************************
* @func int | inFormCPACBatch |
*
* @parm TRANSACTION_OBJECT * | pobTran |
*
* @rdesc
* @end
**********************************************************************************************/

int inFormCPACBatch(TRANSACTION_OBJECT* pobTran) {
    int inTranCode;
    long lnBatchUploadSTAN;
    VS_BOOL fOpenTabOffline;
    char AdjTipAdjflag;

    inTranCode = inGGCode();

	if ((pobTran->srTRTRec.TransactionCode == POINT_BAL_INQ) && 
		(strlen((char *)srISO.pszField61)>=50))  { // for Online Redemption App BNI, POINT BAL
		char buff[128];
        char szBalance[128];
		int i=0;
		for (i=0; i<strlen((char *)srISO.pszField61); i++) {
			if (srISO.pszField61[i]>192) srISO.pszField61[i] = srISO.pszField61[i] - 192;
		}
		memset(buff, 0x00, sizeof(buff));
		strncpy(buff, (char *)&srISO.pszField61[13], 9);
		pobTran->srBRec.lnDepositAmount = strtol(buff, NULL, 10);  //redeemed amount

		memset(buff, 0x00, sizeof(buff));
		strncpy(buff, (char *)&srISO.pszField61[35], 9);
		pobTran->srBRec.lnAmountPerInstallment = strtol(buff, NULL, 10);//redeemed point

		if (!fGetImamAirlineTrx()) {
			memset(pobTran->srBRec.szCustNum, 0x00, sizeof(pobTran->srBRec.szCustNum));
			strncpy(pobTran->srBRec.szCustNum, (char *)&srISO.pszField61[57], 9);  //balance amt/point
			pobTran->srBRec.fCustNum = VS_TRUE;
			pobTran->srBKey.lnTotalOfTransactionAmount = strtol(pobTran->srBRec.szCustNum, NULL, 10);
			LOG_PRINTFF((0x08L, "pobTran->srBRec.szCustNum = %s", pobTran->srBRec.szCustNum));
			LOG_PRINTFF((0x08L, "pobTran->srBKey.lnTotalOfTransactionAmount = %ld", pobTran->srBKey.lnTotalOfTransactionAmount));
		}
		LOG_PRINTFF((0x08L, "FIELD_61: (%s)", (char *)srISO.pszField61)); 
		memset(buff, 0x00, sizeof(buff));
		sprintf(buff, "%ld", strtol(pobTran->srBRec.szCustNum, NULL, 10));
		vdFormatAmount(buff, VS_TRUE);
		memset(szBalance, 0x00, sizeof(szBalance));
		sprintf(szBalance, "POINT %s", buff);
		display_at(1, 6, szBalance, CLR_EOL);
		pobTran->srBRec.lnBaseTransactionAmount = pobTran->srBKey.lnTotalOfTransactionAmount;
		//pobTran->srBRec.lnMessage = SSP_SALE_MSG;
		return VS_SUCCESS;
	}

    if ((pobTran->srTRTRec.TransactionCode == 42) && (pobTran->srBKey.fUploaded != VS_TRUE))   //leo_may3000
        pobTran->srBKey.fUploaded = VS_FALSE;

    if (strlen(pobTran->srBRec.szDate) == DATE_SIZE)

    #ifdef CITI_IND /*last receipt bug*/
        strlcpy(pobTran->srBRec.szDate, &(pobTran->srBRec.szDate[2]), DATE_SIZE);
#endif /*CITI_IND*/

    //leo_uncertainCITIIND effect!@!@!#@!@
#ifndef CITI_IND
    strlcpy(pobTran->srBRec.szDate, &(pobTran->srBRec.szDate[0]), DATE_SIZE);
#endif /*CITI_IND*/


#if 0
   if (pobTran->fReferral || pobTran->srBKey.fOffline)
        lnBatchUploadSTAN = 0L;

   else
 #endif
    lnBatchUploadSTAN = pobTran->srBRec.lnSTAN;

    vdSetCPACBatchUploadSTAN(&pobTran->srBRec, lnBatchUploadSTAN);

    if (pobTran->srBRec.fCloseTabSameCard) {
        if (!fGetDemoMode())
            pobTran->srBRec.lnSTAN = atol((char *) srISO.pszField62);  /* char * added CPAC_LINT */
    } else
        pobTran->srBRec.lnSTAN = lnGetSTAN();

    /* For CASH transaction Amt 1 field is the Cash Amount itself */
    if (inTranCode == CASH_ADV)
        pobTran->srBRec.lnCashBackAmount = pobTran->srBKey.lnTotalOfTransactionAmount;

    if(pobTran->fReferral != VS_TRUE) //KiaSoon 070206: To print Reference Number for sales completion.
    	vdSetCPACRetRefNum(&pobTran->srBRec, srISO.pszField37);

    /*
        Need close tab to save as sale transaction, instead of adjustment
        Set Processing code
    */

    if (inTranCode == PRE_COMP)
        srISO.pszField03[0] = 0x00;

    vdSetCPACProcCode(&pobTran->srBRec, srISO.pszField03);
    vdSetCPACPOSEntryMode(&pobTran->srBRec, srISO.pszField22);

    if (pobTran->fAdjust)
        AdjTipAdjflag = 'A';
    if (pobTran->fTipAdjust)
        AdjTipAdjflag = 'T';
    if (!pobTran->fAdjust && !pobTran->fTipAdjust)
        AdjTipAdjflag = NULL_CH;
    vdSetCPACAdjTipAdjflag(&pobTran->srBRec, AdjTipAdjflag);//bug fix for adj/tip adjust flag
    /*
          Save the Message Type Id
      */

    if ((Mti[1] == 0x10) || (Mti[1] == 0x30))
        Mti[1] = Mti[1] - 0x10; /* Req Msg Id is 0x10 less than resp */

    /*
        Need close tab to save as sale transaction, instead of adjustment
    */

    fOpenTabOffline = fGetCPACOpenTabOffline(&pobTran->srBRec);
    if (inTranCode == PRE_COMP && (!fOpenTabOffline && strncmp(pobTran->srBRec.szAuthCode, "FL", 2)    /* Not floor limit */))
        Mti[1] = 0x00;

    vdSetCPACMsgTypeId(&pobTran->srBRec, Mti);

	if ((pobTran->srTRTRec.TransactionCode == SALE) && 
		(pobTran->srBRec.inInstallments >= 2) && 
		(pobTran->srBRec.inPlan >= 1) && (pobTran->srBRec.inPlan <= 3) &&
		(strlen((char *)srISO.pszField61)>=41))  { // for Installment App BNI
		char buff[30];
		int i=0;
		for (i=0; i<strlen((char *)srISO.pszField61); i++) {
			if (srISO.pszField61[i] > 192){
				srISO.pszField61[i] = srISO.pszField61[i] - 192;
			}
		}
		memset(buff, 0x00, sizeof(buff));
		strcpy(buff, "Fst Pay: ");
		strncat(buff, (char *)&srISO.pszField61[14], 9);
		//	write_at(buff, strlen(buff), 1, 6);
		pobTran->srBRec.lnDepositAmount = strtol(&buff[9], NULL, 10);
		memset(buff, 0x00, sizeof(buff));
		strcpy(buff, "Monthly: ");
		strncat(buff, (char *)&srISO.pszField61[32], 9);
		pobTran->srBRec.lnAmountPerInstallment = strtol(&buff[9], NULL, 10);
		//	write_at(buff, strlen(buff), 1, 7);
		//	SVC_WAIT(1000);
		LOG_PRINTFF((0x08L, "FIELD_61: (%s)", (char *)srISO.pszField61));

		pobTran->srBRec.lnMessage = SSP_SALE_MSG;
	}

	if ((pobTran->srTRTRec.TransactionCode == SALE) && 
		(pobTran->srBRec.inInstallments >= 1) && 
		(pobTran->srBRec.inPlan >= 4) &&
		(strlen((char *)srISO.pszField61)>=50))  { // for Online Redemption App BNI
		char buff[30];
		int i=0;
		for (i=0; i<strlen((char *)srISO.pszField61); i++) {
			if (srISO.pszField61[i]>192) srISO.pszField61[i] = srISO.pszField61[i] - 192;
		}
		memset(buff, 0x00, sizeof(buff));
		strncpy(buff, (char *)&srISO.pszField61[13], 9);
		pobTran->srBRec.lnDepositAmount = strtol(buff, NULL, 10);  //redeemed amount

		memset(buff, 0x00, sizeof(buff));
		strncpy(buff, (char *)&srISO.pszField61[35], 9);
		pobTran->srBRec.lnAmountPerInstallment = strtol(buff, NULL, 10);//redeemed point

		if (!fGetImamAirlineTrx()) {
			memset(pobTran->srBRec.szCustNum, 0x00, sizeof(pobTran->srBRec.szCustNum));
			strncpy(pobTran->srBRec.szCustNum, (char *)&srISO.pszField61[57], 9);  //balance amt/point
			pobTran->srBRec.fCustNum = VS_TRUE;
		}
		LOG_PRINTFF((0x08L, "FIELD_61: (%s)", (char *)srISO.pszField61)); 
		//pobTran->srBRec.lnMessage = SSP_SALE_MSG;
	}

	if ((pobTran->srTRTRec.TransactionCode == VOID) && 
		(pobTran->srBRec.inInstallments >= 1) && 
		(pobTran->srBRec.inPlan >= 4)&& 
		(strlen((char *)srISO.pszField61)>=50))  { // for Online Redemption App BNI) 
		int i=0;
		for (i=0; i<strlen((char *)srISO.pszField61); i++) {
			if (srISO.pszField61[i]>192) srISO.pszField61[i] = srISO.pszField61[i] - 192;
		}
		if (!fGetImamAirlineTrx()) {
			memset(pobTran->srBRec.szCustNum, 0x00, sizeof(pobTran->srBRec.szCustNum));
			strncpy(pobTran->srBRec.szCustNum, (char *)&srISO.pszField61[57], 9);  //balance amt/point
			pobTran->srBRec.fCustNum = VS_TRUE;
		}
	}

	if ((pobTran->srTRTRec.TransactionCode == POINT_BAL_INQ) && 
		(strlen((char *)srISO.pszField61)>=50))  { // for Online Redemption App BNI
		char buff[30];
		int i=0;
		for (i=0; i<strlen((char *)srISO.pszField61); i++) {
			if (srISO.pszField61[i]>192) srISO.pszField61[i] = srISO.pszField61[i] - 192;
		}
		memset(buff, 0x00, sizeof(buff));
		strncpy(buff, (char *)&srISO.pszField61[13], 9);
		pobTran->srBRec.lnDepositAmount = strtol(buff, NULL, 10);  //redeemed amount

		memset(buff, 0x00, sizeof(buff));
		strncpy(buff, (char *)&srISO.pszField61[35], 9);
		pobTran->srBRec.lnAmountPerInstallment = strtol(buff, NULL, 10);//redeemed point

		if (!fGetImamAirlineTrx()) {
			memset(pobTran->srBRec.szCustNum, 0x00, sizeof(pobTran->srBRec.szCustNum));
			strncpy(pobTran->srBRec.szCustNum, (char *)&srISO.pszField61[57], 9);  //balance amt/point
			pobTran->srBRec.fCustNum = VS_TRUE;
			pobTran->srBKey.lnTotalOfTransactionAmount = strtol(pobTran->srBRec.szCustNum, NULL, 10);
			LOG_PRINTFF((0x08L, "pobTran->srBRec.szCustNum = %s", pobTran->srBRec.szCustNum));
			LOG_PRINTFF((0x08L, "pobTran->srBKey.lnTotalOfTransactionAmount = %ld", pobTran->srBKey.lnTotalOfTransactionAmount));
		}
		LOG_PRINTFF((0x08L, "FIELD_61: (%s)", (char *)srISO.pszField61)); 
		//pobTran->srBRec.lnMessage = SSP_SALE_MSG;
	}

	if ( pobTran->srBRec.inCode == SALE && pobTran->srBRec.inTranCardType == DEBIT_CARD) {
		//pobTRan->srBRec.lnMessage = DEBIT_MSG;
	}

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func void | vdCPACBatRec2GDS |
*       The batch record is disassembed and loaded back to GDS for
*       normal use. The batch record has to be loaded by the calling
*       module. The function is called basically for Void and Adjust
*       ISO transactions. fFull will enable loading date, time and
*       amount (it overwrites the GDS amount) and when the variable
*       fTranType == vs_TRUE it overwrites the transaction type
*       also (used for reprinting of reciepts and detail report)
*
* @parm BATCH_REC * | psrBRec |
*
* @rdesc VOID
* @end
**********************************************************************************************/

void vdCPACBatRec2GDS(BATCH_REC* psrBRec) {

    vdGetCPACProcCode(psrBRec, srISO.pszField03);

    vdGetCPACRetRefNum(psrBRec, srISO.pszField37);
    vdGetCPACPOSEntryMode(psrBRec, srISO.pszField22);
    vdGetCPACMsgTypeId(psrBRec, srISO.szMsgTypeId);
	LOG_PRINTFF((0x08L, "CPACBAT srISO.pszField37 [%s]", (char *)srISO.pszField37));
	srISO.pszField03[2]= 0x01;  // jrd 05282005
}

void vdGetCPACProcCode(BATCH_REC* psrBRec,unsigned char* pszData) {
    unsigned char   szProcCode[PROC_CODE_SIZE + 1];
    memset(szProcCode, 0, PROC_CODE_SIZE);
    if (inGetBatchFieldData(psrBRec, CPAC_PROC_CODE, szProcCode, PROC_CODE_SIZE) != VS_ERR) {

	memcpy(pszData, szProcCode, PROC_CODE_SIZE);
        pszData[0] = pszData[0] & 0xF0;
        pszData[2] = 0x01;              // CPAC_UNBKL added CPAC_?


    }
}

void vdSetCPACProcCode(BATCH_REC* psrBRec,unsigned char* pszData) {
    inStoreBatchFieldData(psrBRec, CPAC_PROC_CODE, pszData, PROC_CODE_SIZE);
}

void vdGetCPACRetRefNum(BATCH_REC* psrBRec,unsigned char* pszData) {
    unsigned char   szRetRefNum[RET_REF_SIZE + 1];

    memset(szRetRefNum, 0, RET_REF_SIZE);
    if (inGetBatchFieldData(psrBRec, CPAC_RET_REF, szRetRefNum, RET_REF_SIZE) != VS_ERR)
        memcpy(pszData, szRetRefNum, RET_REF_SIZE);
}

void vdSetCPACRetRefNum(BATCH_REC* psrBRec,unsigned char* pszData) {
    /*
       Store Retrieval Reference Number to host specific portion of batch
    */

    inStoreBatchFieldData(psrBRec, CPAC_RET_REF, pszData, RET_REF_SIZE);
}

void vdGetCPACPOSEntryMode(BATCH_REC* psrBRec,unsigned char* pszData) {
    unsigned char   szPOSEntryMode[POS_EM_SIZE + 1];

    memset(szPOSEntryMode, 0, POS_EM_SIZE);
    if (inGetBatchFieldData(psrBRec, CPAC_POS_EM, szPOSEntryMode, POS_EM_SIZE) != VS_ERR)
        memcpy(pszData, szPOSEntryMode, POS_EM_SIZE);
}

void vdSetCPACPOSEntryMode(BATCH_REC* psrBRec,unsigned char* pszData) {
    /*
       Store POS Entry Mode to host specific portion of batch
    */

    inStoreBatchFieldData(psrBRec, CPAC_POS_EM, pszData, POS_EM_SIZE);
}

void vdGetCPACMsgTypeId(BATCH_REC* psrBRec,unsigned char* pszData) {
    unsigned char   szMsgId[MTI_SIZE + 1];

    memset(szMsgId, 0, MTI_SIZE);
    if (inGetBatchFieldData(psrBRec, CPAC_MTI, szMsgId, MTI_SIZE) != VS_ERR)
        memcpy(pszData, szMsgId, MTI_SIZE);
}

void vdSetCPACMsgTypeId(BATCH_REC* psrBRec,unsigned char* pszData) {
    /*
       Store Message Type ID to host specific portion of batch
     */
    inStoreBatchFieldData(psrBRec, CPAC_MTI, pszData, MTI_SIZE);
}

VS_BOOL fGetCPACOpenTabOffline(BATCH_REC* psrBRec) {
    VS_BOOL fData;

    inGetBatchFieldData(psrBRec, CPAC_BIT_OPEN_TAB_OFFLINE, (unsigned char *) &fData, sizeof(VS_BOOL));
    return fData;
}

void vdSetCPACOpenTabOffline(BATCH_REC* psrBRec,VS_BOOL fData) {
    /*
       Store Message Type ID to host specific portion of batch
     */
    inStoreBatchFieldData(psrBRec, CPAC_BIT_OPEN_TAB_OFFLINE, (unsigned char *) &fData, sizeof(VS_BOOL));
}

long lnGetCPACBatchUploadSTAN(BATCH_REC* psrBRec) {
    long lnData;

    if (inGetBatchFieldData(psrBRec, CPAC_BATCH_UPLOAD_STAN, (unsigned char *) &lnData, sizeof(long)) != VS_ERR)
        return(lnData);
    else
        return((long) VS_ERR);
}

void vdSetCPACBatchUploadSTAN(BATCH_REC* psrBRec,long lnData) {
    /*
       Store Message Type ID to host specific portion of batch
     */
    inStoreBatchFieldData(psrBRec, CPAC_BATCH_UPLOAD_STAN, (unsigned char *) &lnData, sizeof(long));
}

void vdSetCPACUserInvNum(BATCH_REC* psrBRec,unsigned char* pszData) {
    /*
     *      Store Transaction Identifier to host specific portion of batch
     */
    inStoreBatchFieldData(psrBRec, CPAC_USR_INV_NUM_ID, pszData, CPAC_USR_INV_NUM_SIZE);
}

void vdGetCPACUserInvNum(BATCH_REC* psrBRec,unsigned char* pszData) {
    unsigned char   szUsrInvNum[CPAC_USR_INV_NUM_SIZE + 1];

    memset(szUsrInvNum, 0, CPAC_USR_INV_NUM_SIZE);
    if (inGetBatchFieldData(psrBRec, CPAC_USR_INV_NUM_ID, szUsrInvNum, CPAC_USR_INV_NUM_SIZE) != VS_ERR)
        memcpy(pszData, szUsrInvNum, CPAC_USR_INV_NUM_SIZE);
}
void vdSetCPACAdjTipAdjflag(BATCH_REC* psrBRec,char  pszData)//bug fix for adj/tip adjust flag
{
    inStoreBatchFieldData(psrBRec, CPAC_ADJTIP_FLAG, (unsigned char *) &pszData, sizeof(char));
}

char chGetCPACAdjTipAdjflag(BATCH_REC* psrBRec,unsigned char* pszData) {
    unsigned char chData;

    if (inGetBatchFieldData(psrBRec, CPAC_ADJTIP_FLAG, &chData, 1) != VS_ERR)
        memcpy(pszData, &chData, 1);

    return((char) VS_SUCCESS);
}


void vdGetTCFlag (BATCH_REC *psrBRec, unsigned char * pszData)
{
	unsigned char szBuff[10+1];
    memset (szBuff, 0x00, sizeof(szBuff));
	if ( inGetBatchFieldData (psrBRec, IMAM_TC_FLAG, szBuff, 10) != VS_ERR ){
	    memcpy(pszData, szBuff, 10);
	}
	LOG_PRINTFF((0x08L, "GET TC FLAG = [%s]", (char *)pszData));
}

void vdSetTCFlag (BATCH_REC *psrBRec, unsigned char * pszData)
{
	LOG_PRINTFF((0x08L, "STORE TC FLAG = [%s]", (char *)pszData));
    inStoreBatchFieldData (psrBRec, IMAM_TC_FLAG, pszData, 10);
}


void vdImamGetCTLData (BATCH_REC *psrBRec, unsigned char * pszData)
{
	unsigned char szBuff[128+1];
    memset (szBuff, 0x00, sizeof(szBuff));
	if ( inGetBatchFieldData (psrBRec, IMAM_CTL_DATA, szBuff, 128) != VS_ERR ){
	    memcpy(pszData, szBuff, 128);
	}
	//LOG_PRINTFF((0x08L, "GET CHIP DATA = [%s]", (char *)pszData));
}

void vdImamSaveCTLData (BATCH_REC *psrBRec, unsigned char * pszData)
{
    inStoreBatchFieldData (psrBRec, IMAM_CTL_DATA, pszData, 128);
}

#ifdef CITI_PHIL

/*********************************************************************************************
* @func int | inCITIOpenTabRetrieveInv |
*
*       This function prompts user to choose which search path
*       they want for OPENTAB - Invoice number or last 5 digits of
*       account number.
*
* @parm TRANSACTION_OBJECT *    | pobTran   |
*
* @rdesc Return values.
*
* @flag int    |    VS_SUCCESS
*                   VS_ESCAPE
* @end
**********************************************************************************************/

int inCITIOpenTabRetrieveInv(TRANSACTION_OBJECT* pobTran) {
    long lnDBWhat = DB_FIRST;
    int inRetVal;

    /** /pdebug(("--inRetrieveInvOrAcct--"));*/
    do {
        inRetVal = inGetInvoiceNumber(pobTran);
        if (inRetVal != VS_SUCCESS) {
            inRetVal = VS_ERR;
            break;
        }
        if (inRetVal == VS_ESCAPE)
            break;
        if ((inRetVal = inGetOTInvBatchRec(pobTran, KEY_INV_NUM, lnDBWhat)) != VS_SUCCESS) //1.4
            vdDisplayMessageFromFile(NO_MATCH_MSG21, ERROR_MSG);
    } while (inRetVal != VS_SUCCESS);




    if (inRetVal == VS_ESCAPE)
        vdSGErrorMessage(0L);

    return (inRetVal);
}

#endif /* CITI_PHIL */
#endif /* AMEXPIP */


